# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                             QHBoxLayout, QLabel, QLineEdit, QPushButton,
                             QTableWidget, QTableWidgetItem, QHeaderView,QMessageBox,QDesktopWidget,QStyleFactory)
                             
from PyQt5.QtGui import QIcon,QFont

from tqsdk import TqApi, TqAuth, TqAccount
from PyQt5.QtCore import QObject, pyqtSignal  # 将此导入语句移动到文件顶部

class CapitalManager(QMainWindow):
    update_signal = pyqtSignal(str)
    connection_signal = pyqtSignal(str, bool)

    def _connect_thread(self):
        try:
            # 修正经纪商代码为官方格式（关键修复）
            self.tq_account = TqAccount("H徽商期货", "155831", "alibaba999")  # 必须使用官方代码
            self.api = TqApi(account=self.tq_account,
                           auth=TqAuth("szlwy68", "alibaba999"),
                           _stock=False)
            
            # 延长超时时间为20秒
            import time
            timeout = time.time() + 20  # 延长至20秒
            while not hasattr(self.api._account, '_has_login') or not self.api._account._has_login:
                if time.time() > timeout:
                    raise TimeoutError("连接超时")
                self.api.wait_update()
                print("链接成功")
                print("当前账户可用资金：",myacc.available)
            
            # 添加初始化等待（关键）
            import time
            timeout = time.time() + 10  # 10秒超时
            while not hasattr(self.api._account, '_has_login') or not self.api._account._has_login:
                if time.time() > timeout:
                    raise TimeoutError("连接超时")
                self.api.wait_update()
            
            # 发射连接成功信号
            self.connection_signal.emit("已连接 (点击断开)", True)
            self.update_capital()  # 启动资金更新线程
            
        except Exception as e:
            self.connection_signal.emit(f"连接失败: {str(e)}", False)

    def handle_connection(self, text, success):
        """处理连接状态更新"""
        self.connect_btn.setText(text)
        self.connect_btn.setEnabled(True)
        if success:
            self.connect_btn.clicked.disconnect()
            self.connect_btn.clicked.connect(self.disconnect_tq)
            # 立即触发首次更新（关键修复）
            QApplication.processEvents()
            self.update_capital()

    def update_capital(self):
        """更新账户资金线程"""
        def worker():
            try:
                # 添加更完善的账户验证
                while self.api and not hasattr(self.api._account, 'account_id'):
                    self.api.wait_update()
                
                # 主动查询账户信息（关键修复）
                account = self.api.get_account()
                while True:
                    self.api.wait_update()
                    if account.available != account._last_available:
                        self.update_signal.emit(f"{account.available:.2f}")
                    account._last_available = account.available
            except Exception as e:
                print(f"更新异常: {str(e)}")
                
        from threading import Thread
        Thread(target=worker, daemon=True).start()

    def __init__(self):
        super().__init__()
        self.setWindowTitle("资金管理系统")
        self.resize(800, 600)  # 添加固定窗口尺寸
        self.init_ui()

    def init_ui(self):
        # 创建主控件和布局（必须首先完成）
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)

        # ==== 创建所有UI组件 ====
        # 连接按钮
        self.connect_btn = QPushButton("连接天勤账户")
        self.connect_btn.clicked.connect(self.connect_tq)
        layout.addWidget(self.connect_btn)

        # 输入区域
        input_layout = QHBoxLayout()
        # 资金输入
        self.capital_input = QLineEdit()
        self.capital_input.setPlaceholderText("正在获取账户资金...")
        self.capital_input.setReadOnly(True)
        input_layout.addWidget(QLabel("账户可用资金:"))
        input_layout.addWidget(self.capital_input)
        
        # 风险比例输入
        self.risk_input = QLineEdit()
        self.risk_input.setPlaceholderText("输入风险比例（%）")
        self.risk_input.setText("20")
        input_layout.addWidget(QLabel("风险比例:"))
        input_layout.addWidget(self.risk_input)
        layout.addLayout(input_layout)

        # 计算按钮
        self.calc_btn = QPushButton("计算开仓量")
        self.calc_btn.clicked.connect(self.calculate)
        layout.addWidget(self.calc_btn)

        # 结果表格
        self.table = QTableWidget()
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(["品种", "保证金", "止损金额", "建议开仓量", "最大开仓量"])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        layout.addWidget(self.table)

        # 说明标签
        explanation = QLabel("""<span style='color: blue; font-size: 10pt'>
        计算公式说明：<br/>
        1. 最大开仓量 = (账户资金 × 风险比例) / 每手保证金（取整）<br/>
        2. 建议开仓量 = 最大开仓量 // 3
        </span>""")
        explanation.setContentsMargins(5, 5, 5, 10)
        layout.addWidget(explanation)

        # ==== 最后连接信号 ====
        self.connection_signal.connect(self.handle_connection)
        self.update_signal.connect(self.capital_input.setText)

        # 设置布局伸缩比例
        layout.setStretch(0, 0)   # 输入区域
        layout.setStretch(1, 0)   # 按钮
        layout.setStretch(2, 9)    # 表格
        layout.setStretch(3, 1)    # 说明

    def calculate(self):
        # 获取并清理输入
        capital_text = self.capital_input.text().strip()
        risk_text = self.risk_input.text().strip()
        
        # 增加空值校验
        if not capital_text or not risk_text:
            QMessageBox.warning(self, "输入错误", "请输入完整的数值")
            return

        try:
            # 转换前移除非数字字符
            capital = float(capital_text.replace(',', ''))
            risk_percent = float(risk_text.replace('%', '')) / 100
        except ValueError:
            QMessageBox.warning(self, "输入错误", "请输入有效的数字")
            return

        self.table.setRowCount(0)

        for product in self.products:
            # 修改后的最大开仓量计算
            risk_capital = capital * risk_percent  # 风险资金
            margin = product['margin'] or 1
            max_lots = int(risk_capital / margin)
            
            # 建议开仓量计算保持不变
            suggested = max_lots // 3
            
            # 计算风险金额（仅用于显示）
            risk_per_lot = product['stoploss'] * product['multiplier']

            # 添加表格行（新增保证金列）
            row = self.table.rowCount()
            self.table.insertRow(row)
            
            # 调整列顺序（交换品种和保证金位置）
            self.table.setItem(row, 0, QTableWidgetItem(product['name']))      # 第一列：品种
            self.table.setItem(row, 1, QTableWidgetItem(str(product['margin'])))  # 第二列：保证金
            self.table.setItem(row, 2, QTableWidgetItem(f"{risk_per_lot:.2f}元")) 
            self.table.setItem(row, 3, QTableWidgetItem(str(suggested)))
            self.table.setItem(row, 4, QTableWidgetItem(str(max_lots)))

        # 添加表格刷新（新增）
        self.table.viewport().update()


        # 添加全局字体设置
    def connect_tq(self):
        """连接天勤账户"""     
        try:
            self.connect_btn.setEnabled(False)  # 禁用按钮防止重复点击
            self.connect_btn.setText("连接中...")
            
            # 创建后台线程
            from threading import Thread
            Thread(target=self._connect_thread, daemon=True).start()
            
        except Exception as e:
            self.connect_btn.setEnabled(True)
            QMessageBox.critical(self, "错误", f"启动连接失败: {str(e)}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 样式设置应该在窗口创建前完成（关键）
    app.setStyle(QStyleFactory.create("WindowsVista"))
    app.setFont(QFont("微软雅黑", 9))
    app.setStyleSheet("""
        * {
            font-family: "微软雅黑", "Consolas";
        }
        QLineEdit, QTableWidget, QLabel {
            font: 10pt "Consolas", "微软雅黑";
        }
    """)
    app.setWindowIcon(QIcon('app.png'))
    window = CapitalManager()
    window.show()
    sys.exit(app.exec_())